﻿using System;
using System.Collections.Generic;
using System.Web.Http;
using Castle.Core.Logging;
using JWT;
using JWT.Algorithms;
using JWT.Serializers;
using Hiver.Entity;
using Hiver.Business;
using Hiver.WebApi.Models;
using Hiver.WebApi.Models.Request;
using Hiver.WebApi.Models.Response;

namespace Hiver.WebApi.Controllers
{
    /// <summary>
    /// Auth控制器（高级接口）
    /// </summary>
    public class AuthController : ApiController
    {
        /// <summary>
        /// 日志
        /// </summary>
        public ILogger Logger { get; set; }

        /// <summary>
        /// 用户服务
        /// </summary>
        public IUserService service { get; set; }

        /// <summary>
        /// 用户登录
        /// </summary>
        /// <param name="auth"></param>
        /// <returns></returns>
        [Route("api/Auth/Login")]
        [HttpPost]
        public BaseModel<AuthResponseInfo> Login([FromBody] AuthRequestInfo auth)
        {
            BaseModel<AuthResponseInfo> model = new BaseModel<AuthResponseInfo>();
            UserInfo userInfo = service.Login(auth.username, auth.password);
            if (userInfo != null && userInfo.Id > 0)
            {
                try
                {
                    AuthInfo info = new AuthInfo { id = userInfo.Id, username = userInfo.UserName, roles = new List<string> { "admin", "manage" }, isAdmin = true };
                    const string secret = "1qazxsw2#";
                    IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
                    IJsonSerializer serializer = new JsonNetSerializer();
                    IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
                    IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);
                    var token = encoder.Encode(info, secret);
                    model.code = 200;
                    AuthResponseInfo response = new AuthResponseInfo();
                    response.token = token;
                    response.id = userInfo.Id;
                    response.name = userInfo.UserName;
                    model.msg = "登录成功";
                    model.data = response;
                }
                catch (Exception ex)
                {
                    model.code = 500;
                    model.msg = ex.Message;
                }
            }
            else
            {
                model.code = 500;
                model.msg = "登录失败";
            }
            return model;
        }

        /// <summary>
        /// 获得用户信息
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        [Route("api/Auth/User")]
        public BaseModel<UserInfo> GetUserInfo(string token)
        {
            BaseModel<UserInfo> model = new BaseModel<UserInfo>();
            try
            {
                const string secret = "1qazxsw2#";
                IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
                IJsonSerializer serializer = new JsonNetSerializer();
                IDateTimeProvider provider = new UtcDateTimeProvider();
                IJwtValidator validator = new JwtValidator(serializer, provider);
                IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
                IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder, algorithm);
                var json = decoder.DecodeToObject<AuthInfo>(token, secret, verify: true);
                if (json != null)
                {
                    // 获得用户名
                    UserInfo userInfo = service.Get(json.id);
                    model.data = userInfo;
                }
                else
                {
                    model.code = 404;
                    model.msg = "令牌不正确";
                }
            }
            catch (Exception ex)
            {
                Logger.Error(ex.Message, ex);
                model.code = 500;
                model.msg = ex.Message;
            }
            return model;
        }

        /// <summary>
        /// 用户注销
        /// </summary>
        /// <returns></returns>
        [Route("api/Auth/Logout")]
        [HttpPost]
        // [ApiAuthorize]
        public BaseModel<bool> Logout()
        {
            BaseModel<bool> model = new BaseModel<bool>();
            model.data = true;
            model.msg = "注销成功";
            return model;
        }
    }
}